﻿using System.Collections.Generic;
using System.Globalization;
using System.Xml;
using BlogsAPI.GeoLocation;
using BlogsAPI.Interfaces;
using Newtonsoft.Json.Linq;

namespace BlogsAPI.Sites
{
    using System.Web;
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Text.RegularExpressions;
    using Abstract;
    using RssToolkit.Rss;
    using System.Linq;

    /// <summary>
    /// Videohost - DailyMotion.com
    /// </summary>
    [BlogServiceAPI(Description = "DailyMotion", Link = "http://DailyMotion.com")]
    public class DailyMotion : BlogServer, IVideoHost
    {
        /// <summary>
        /// http://www.dailymotion.com/video/x4o4hnl_download-electrician-s-technical-reference-electrical-theory-and-calculations-paperback-online_news
        /// </summary>
        private static readonly Regex Validation = new Regex(@"^https?://(?:[-_\w]+\.)?dailymotion\.com/video/([\w_-]+)", Regexoptions);

        ///// <summary>
        ///// <dm:views>
        ///// </summary>
        private static readonly Regex viewsNumber = new Regex(@"<dm:views>([^<]+)<", Regexoptions);

        /// <summary>
        /// <dm:comments>
        /// </summary>
        private static readonly Regex commsNumber = new Regex(@"<dm:comments>([^<]+)<", Regexoptions);

        private static readonly Regex uploadDate = new Regex(@"<pubDate>([^<]+)<", Regexoptions);

        private static readonly Regex rThumbnail2 = new Regex(@"<media:thumbnail[^>]+?url\W+([^""]+)\W", Regexoptions);
        private static readonly Regex Title = new Regex(@"<media:title>([^<]+)<", Regexoptions);
        private static readonly Regex Tags = new Regex(@"<media:category[^>]+>([^<]+)<", Regexoptions);

        private static readonly Regex UserID = new Regex(@"<dm:author>([^<]+)<", Regexoptions);

        #region interface: BlogServer

        [DebuggerStepThrough]
        public DailyMotion()
        {
            Encoding = Encoding.UTF8;
        }

        public override bool ValidateLink(string link)
        {
            string userName;
            BlogType bt;
            return ValidateLink(link, out userName,out bt);
        }

        /// <summary>
        /// проверка, является ли передаваемый урл чатью этого сервиса
        /// </summary>
        public override Boolean ValidateLink(string link, out string userName, out BlogType bType)
        {
            userName = "";
            bType = BlogType.User;
            return Validation.Match(link).Success;
        }


        /// <summary>
        /// Получение ссылки на блог блогера
        /// </summary>
        /// <param name="userName">ник блогера</param>
        /// <param name="btype">Тип блога - пользователь или сообщество</param>
        public override String GetBlogLink(string userName, BlogType btype)
        {
            //http://www.dailymotion.com/louise-halle
            return String.Format("http://www.dailymotion.com/{0}", userName);
        }

        /// <summary>
        /// Извлечение картинки пользователя
        /// </summary>
        /// <param name="userName">имя блогера</param>
        /// <param name="btype">тип блога</param>
        /// <returns>Прямая ссылка на картинку</returns>
        public override string ExtractAvatar(string userName, BlogType btype)
        {
            string sAva = string.Empty;
            try
            {
                //http://www.dailymotion.com/rss/louise-halle
                var rss = RssDocument.Load(new Uri(String.Format("http://www.dailymotion.com/rss/{0}", userName)), true);
                sAva = rss.Channel.Items.FirstOrDefault(p => p.MediaThumbnail != null && !String.IsNullOrEmpty(p.MediaThumbnail.url)).MediaThumbnail.url;
            }
            catch(Exception e1)
            {
                Debug.Write(e1);
            }
            return sAva;
        }

        #endregion

        #region IVideoHost

        /// <summary>
        /// Получение данных по ссылке
        /// </summary>
        /// <param name="link"></param>
        /// <example>http://www.dailymotion.com/video/x29pacj_ukraine-rebels-seen-moving-large-military-convoys_news</example>
        /// <returns></returns>
        public Tuple<VideoData, BlogPost> GetVideoData(Uri link)
        {
            var oRet = new Tuple<VideoData, BlogPost>(
                new VideoData(link),
                new BlogPost(link) { Existance = false,Links = 0,Comments = 0});
            try
            {
                if (ValidateLink(link.OriginalString))
                {
                    var myHttpWebRequest = Common.MakeRequest(link.OriginalString.Replace("/video/", "/rss/video/"));
                    var myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                    if (myHttpWebResponse.StatusCode == HttpStatusCode.OK)
                    {
                        string reply = new StreamReader(myHttpWebResponse.GetResponseStream()).ReadToEnd();
                        Match img = rThumbnail2.Match(reply);
                        oRet.Item2.Attributes = new PostAttributeCollection();
                        if (img.Success)
                        {
                            var imgLink = img.Groups[1].Value;
                            oRet.Item1.Replace = "<a href=\"" +
                                      link.OriginalString + "\"><img src=\"" + imgLink +
                                      "\"/>[Видео]</a>";
                            oRet.Item1.Images += "<img src=\"" + imgLink + "\"/>";
                            oRet.Item2.Attributes.Add(new PostAttribute(PostParams.MediaThumbnail,
                                imgLink));
                        }
                        //а теперь просмотры!
                        Match vs = viewsNumber.Match(reply);
                        if (vs.Success)
                        {
                            oRet.Item1.Views += int.Parse(vs.Groups[1].Value);
                            oRet.Item2.Views = oRet.Item1.Views;
                        }
                        //комментарии
                        vs = commsNumber.Match(reply);
                        if (vs.Success)
                        {
                            oRet.Item2.Comments += int.Parse(vs.Groups[1].Value);
                        }
                        //
                        Match pDate = uploadDate.Match(reply);
                        if (!pDate.Success || !DateTime.TryParse(pDate.Groups[1].Value.Trim(),
                            new CultureInfo("en-US"), DateTimeStyles.AssumeUniversal,
                            out oRet.Item1.Published))
                        {
                            oRet.Item1.Published = DateTime.UtcNow; //чтобы не вставить текущий день
                        }
                        else
                        {
                            oRet.Item1.Published = oRet.Item1.Published;//сдвиг в зону UTC
                        }
                        oRet.Item2.Published = oRet.Item1.Published;
                        //формирование поста...
                        MatchCollection mc = Title.Matches(reply);
                        if (mc.Count > 0)
                        {
                            oRet.Item1.Title =
                            oRet.Item2.Subject =
                            mc[mc.Count - 1].Groups[1].Value.Trim();
                        }
                        Match userid = UserID.Match(reply);
                        if (userid.Success)
                        {
                            oRet.Item2.SpecialParam = userid.Groups[1].Value;
                        }
                        mc = Tags.Matches(reply);
                        if (mc.Count > 0)
                        {
                            var tags = mc.Cast<Match>().Select(match => match.Groups[1].Value.ToLower()).Distinct().ToArray();
                            oRet.Item2.Attributes.Add(new PostAttribute(PostParams.Tags,
                                String.Join(",", tags)));
                        }

                        oRet.Item2.Existance = true;
                        oRet.Item2.Links = 0;
                    }
                    myHttpWebResponse.Close();
                }
            }
            catch (Exception e1)
            {
                Debug.Write(e1);
            }
            return oRet;
        }

        /// <summary>
        /// Вычисление цифр
        /// </summary>
        readonly static Regex digi = new Regex(@"/video/([^_-]+)_", Regexoptions);

        /// <summary>
        /// Код для размещения на сторонних ресурсах
        /// </summary>
        /// <param name="link"></param>
        /// <returns></returns>
        public string FormEmbedCode(Uri link, String preview = null)
        {
            if (String.IsNullOrEmpty(preview)) return null;
            var m = digi.Match(preview);
            if (m.Success)
            {
                return String.Format(
                    "<iframe frameborder=\"0\" width=\"480\" height=\"270\" src=\"//www.dailymotion.com/embed/video/{0}\" allowfullscreen></iframe>",
                    m.Groups[1].Value);
            }
            return String.Empty;
        }

        #endregion
    }
}